{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Building Firmware"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "PLATFORM = 'CWLITEARM'\n",
    "CRYPTO_TARGET = 'NONE'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash -s \"$PLATFORM\" \"$CRYPTO_TARGET\"\n",
    "cd ../../hardware/victims/firmware/your_project\n",
    "make PLATFORM=$1 CRYPTO_TARGET=$2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Capture"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import chipwhisperer as cw\n",
    "scope = cw.scope()\n",
    "target = cw.target(scope)\n",
    "scope.default_setup()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fw_path = \"../../hardware/victims/firmware/path/to/binary\"\n",
    "prog = cw.programmers.STM32FProgrammer\n",
    "#prog = cw.programmers.XMEGAProgrammer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cw.program_target(scope, prog, fw_path)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create Project"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "project = cw.create_project(\"projects/project_name.cwp\", overwrite=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Basic Capture Loop (For Analyzer)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Capture Traces\n",
    "from tqdm import tqdm\n",
    "import numpy as np\n",
    "import time\n",
    "\n",
    "ktp = cw.ktp.Basic(target=target)\n",
    "\n",
    "N = 50  # Number of traces\n",
    "for i in tqdm(range(N), desc='Capturing traces'):\n",
    "\n",
    "    key, text = ktp.next()  # manual creation of a key, text pair can be substituted here\n",
    "    ret = cw.capture_trace(scope, target, text, key)\n",
    "    if not ret:\n",
    "        continue\n",
    "    wave, textout = ret\n",
    "    project.traces.append((wave, text, textout, key))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Basic Capture Loop (No Project)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Capture Traces\n",
    "from tqdm import tqdm\n",
    "import numpy as np\n",
    "import time\n",
    "\n",
    "ktp = cw.ktp.Basic(target=target)\n",
    "\n",
    "traces = []\n",
    "textin = []\n",
    "keys = []\n",
    "N = 50  # Number of traces\n",
    "for i in tqdm(range(N), desc='Capturing traces'):\n",
    "    # run aux stuff that should come before trace here\n",
    "\n",
    "    key, text = ktp.newPair()  # manual creation of a key, text pair can be substituted here\n",
    "    textin.append(text)\n",
    "    keys.append(key)\n",
    "    ret = cw.capture_trace(scope, target, text, key)\n",
    "    if not ret:\n",
    "        continue\n",
    "    wave, textout = ret\n",
    "    traces.append(wave)\n",
    "\n",
    "#Convert traces to numpy arrays\n",
    "trace_array = np.asarray(traces)  # if you prefer to work with numpy array for number crunching\n",
    "textin_array = np.asarray(textin)\n",
    "known_keys = np.asarray(keys)  # for fixed key, these keys are all the same"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Multiple Trace Capture\n",
    "\n",
    "Captures multiple traces with the same plaintext and stitches them together. This is helpful for algorithms with very long traces (such as RSA)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def run_multi_trace(scope, target, start, step, num_step):\n",
    "    scope.adc.samples = step\n",
    "    num_stepped = 0\n",
    "    trace = np.zeros(step*num_step)\n",
    "    while num_stepped < num_step:\n",
    "\n",
    "        scope.adc.offset = start + (step * num_stepped)\n",
    "\n",
    "        # run aux stuff that should run before the scope arms here\n",
    "        scope.arm()\n",
    "\n",
    "        # run aux stuff that should run after the scope arms here\n",
    "\n",
    "        target.go()\n",
    "        # wait for target to finish\n",
    "        while target.isDone() is False:\n",
    "            timeout -= 1\n",
    "            time.sleep(0.01)\n",
    "\n",
    "        try:\n",
    "            ret = scope.capture()\n",
    "            if ret:\n",
    "                print('Timeout happened during acquisition')\n",
    "        except IOError as e:\n",
    "            print('IOError: %s' % str(e))\n",
    "\n",
    "        # run aux stuff that should happen after trace here\n",
    "\n",
    "        #_ = target.readOutput() # throw out the target response\n",
    "        # append the new trace\n",
    "        new_trace = scope.getLastTrace()\n",
    "        if len(new_trace) < step:\n",
    "            new_trace = np.zeros(step)\n",
    "        trace[((num_stepped) * step):((num_stepped+1) * step)] = new_trace\n",
    "        num_stepped += 1\n",
    "    return trace"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Saving Project Traces"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "project.save()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Disconnect"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# cleanup the connection to the target and scope\n",
    "scope.dis()\n",
    "target.dis()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Analysis (With Analyzer)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Loading Project"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import chipwhisperer as cw\n",
    "import chipwhisperer.analyzer as cwa\n",
    "project = cw.open_project(\"projects/Your project\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Setting up Attack"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import chipwhisperer as cw\n",
    "attack = cw.cpa(project, cw.leakage_models.sbox_output)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Attack With Table"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cb = cw.get_jupyter_callback(attack)\n",
    "attack_results = attack.run(cb)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Plot Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plot_data = cw.analyzer_plots(attack_results)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "rets = []\n",
    "for i in range(16):\n",
    "    rets.append(plot_data.outputVsTime(i))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for bnum in range(16):\n",
    "    ret = plot_data.pgeVsTrace(bnum)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for bnum in range(16):\n",
    "    ret = plot_data.corrVsTrace(bnum)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Plotting With Bokeh"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from bokeh.plotting import figure, show\n",
    "from bokeh.io import output_notebook\n",
    "\n",
    "output_notebook()\n",
    "p = figure()\n",
    "p.line(xdata, ydata, line_color=\"red\")\n",
    "show(p)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Other"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Serial Read"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "response = target.read()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Resetter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "def reset_target(scope):\n",
    "    scope.io.nrst = 'low'\n",
    "    #scope.io.pdic = 'low'\n",
    "    time.sleep(0.05)\n",
    "    scope.io.nrst = 'high'\n",
    "    #scope.io.pdic = 'high'"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
